<template>
  <div class="test">
    <n-card size="medium">
      <div class="button">
        <div>
          <n-button type="success">类型</n-button>
        </div>
        <div>
          <n-button
            @click="buttonObj.defaultValue = !buttonObj.defaultValue"
            :type="buttonObj.defaultValue ? 'success' : 'default'"
          >
            默认值
          </n-button>
        </div>
        <div>
          <n-button
            @click="buttonObj.rule = !buttonObj.rule"
            :type="buttonObj.rule ? 'success' : 'default'"
          >
            验证
          </n-button>
        </div>
        <div>
          <n-button
            @click="buttonObj.layout = !buttonObj.layout"
            :type="buttonObj.layout ? 'success' : 'default'"
          >
            布局
          </n-button>
        </div>
        <div>
          <n-button
            @click="buttonObj.showSlot = !buttonObj.showSlot"
            :type="buttonObj.showSlot ? 'success' : 'default'"
          >
            插槽
          </n-button>
        </div>
        <div>
          <n-button
            @click="showConfig = !showConfig"
            :type="showConfig ? 'success' : 'default'"
          >
            显示配置
          </n-button>
        </div>
      </div>
    </n-card>
    <n-card size="medium" style="margin-top: 10px">
      <div
        class="row"
        v-for="(option, index) in settingOptionFilter"
        :key="index"
      >
        <div class="label">
          {{ option.label }}
          <n-popover
            placement="right"
            trigger="click"
            :width="600"
            v-if="showConfig"
          >
            <template #trigger>
              <n-button
                size="small"
                type="success"
                style="margin-left: 10px; margin-bottom: 10px"
                @click="handleConfigClick(null, index)"
              >
                显示本行配置
              </n-button>
            </template>
            <div class="large-text">
              <n-input
                :value="config"
                type="textarea"
                placeholder="123"
                size="medium"
                :maxRows="100"
                :rows="30"
              ></n-input>
            </div>
          </n-popover>
        </div>
        <pro-form
          :ref="`proFormRef${index}`"
          :options="option.option"
          :showSubmitButton="buttonObj.rule ? true : false"
          :showResetButton="buttonObj.rule ? true : false"
          :formProps="formProps"
          :form="form[index]"
          @formItemChange="handleChange"
        >
          <template v-if="buttonObj.showSlot" #before>
            <n-tag type="success" style="margin: 0 5px">前置</n-tag>
          </template>
          <template v-if="buttonObj.showSlot" #after>
            <n-tag type="success" style="margin: 0 5px">后置</n-tag>
          </template>
          <template v-if="showConfig" #after="{ column }">
            <n-popover placement="right" trigger="click" :width="600">
              <template #trigger>
                <n-button
                  size="small"
                  type="success"
                  style="margin-left: 10px"
                  @click="handleConfigClick(column, index)"
                >
                  配置
                </n-button>
              </template>
              <div class="large-text">
                <n-input
                  :value="config"
                  type="textarea"
                  size="medium"
                  :autosize="{ maxRows: 100 }"
                  :rows="30"
                ></n-input>
              </div>
            </n-popover>
          </template>
        </pro-form>
      </div>
    </n-card>
  </div>
</template>

<script lang="ts" setup name="test">
  import { cloneDeep } from 'lodash-es'
  import { FormProps, NButton } from 'naive-ui'
  import type { Ref } from 'vue'
  import { ProFormOptions } from '@/components/pro-form/type'
  import {
    option1,
    option2,
    option3,
    option4,
    option5,
    option6,
    option7,
    option8,
    option9,
    option10,
    option11
  } from './setting'
  const { proxy } = getCurrentInstance()

  type settingOptionType = {
    label: string
    option: ProFormOptions
  }

  const formProps: FormProps = {
    labelPlacement: 'left'
  }
  const form: Ref<Array<object>> = ref([])

  const formInit: Array<object> = [
    {
      phone: '123456',
      name: 'Mick',
      inputNumber: 99,
      inputTextarea: 'hello'
    },
    {
      sex: 'boy',
      tree: 'Rubber Soul'
    },
    {
      cascader: '1'
    },
    {
      date: '2000-09-18',
      time: '11:22:30',
      monthrange: ['2022-08', '2022-09']
    },
    {
      switch: true
    },
    {
      checkbox: true,
      checkboxGroup: ['Option 1'],
      radio: true,
      radioGroup: 'Radio 1'
    },
    {
      color: 'red'
    },
    {
      slider: 20
    },
    {
      transfer: [1]
    }
  ]

  const settingOption: Array<settingOptionType> = [
    {
      label: '输入框',
      option: option1
    },
    {
      label: '下拉框',
      option: option2
    },
    {
      label: '级联',
      option: option3
    },
    {
      label: '日期时间',
      option: option4
    },
    {
      label: '切换按钮',
      option: option5
    },
    {
      label: '选项',
      option: option6
    },
    {
      label: '颜色',
      option: option7
    },
    {
      label: '进度',
      option: option8
    },
    {
      label: '穿梭',
      option: option9
    },
    {
      label: 'render',
      option: option10
    },
    {
      label: '宽度',
      option: option11
    }
  ]

  const handleChange = (...args) => {
    window['$message'].success(`变化后的数据为${args[0]}`)
  }

  const buttonObj = reactive({
    type: true,
    defaultValue: false,
    rule: false,
    layout: false,
    showSlot: false
  })

  /**
   * @description: 表单选项的计算属性
   * @param {*} computed
   * @return {*}
   */
  const settingOptionFilter = computed(() => {
    const temp: Array<settingOptionType> = cloneDeep(settingOption)
    // 去掉规则验证
    if (!buttonObj.rule) {
      temp.forEach((item) => {
        item.option.forEach((option) => {
          // 改变布局
          if (buttonObj.layout) {
            if (option.grid) option.grid.cols = '2'
          }
          if (option.columnItemList) {
            option.columnItemList.forEach((column) => {
              column.formItem.rule = {}
            })
          }
        })
      })
    } else if (buttonObj.layout) {
      // 改变布局
      temp.forEach((item) => {
        item.option.forEach((option) => {
          if (option.grid) {
            option.grid.cols = '2'
          }
          if (option.columnItemList) {
            option.columnItemList.forEach((column) => {
              column.formItem.rule = {}
            })
          }
        })
      })
    }
    // 是否显示配置文件
    if (showConfig.value) returnConfig(temp)
    return temp
  })
  // 是否显示配置文件
  const showConfig = ref(false)
  // 配置文件对象
  const config = ref('')
  // 选中下标
  const selectedIndex = ref(0)
  // 选中下标
  const selectedkey = ref('')
  /**
   * @description: 设置配置对象
   * @param {*} configList
   * @return {*}
   */
  const returnConfig = (configList: Array<any>) => {
    let option = configList[selectedIndex.value].option
    if (selectedkey.value) {
      option = configList[selectedIndex.value].option[0].columnItemList.find(
        (column) => {
          return column.formItem.key === selectedkey.value
        }
      )
    }
    const str = JSON.stringify(option)
    config.value = handleStringPrefShow(str)
  }

  /**
   * @description: JSON字符串展示优化(间距，双引号)
   * @param {*} str
   * @return {*}
   */
  const handleStringPrefShow = (str: string): string => {
    // 返回的结果字符串
    let newStr = ''
    // 间隔字符串
    let indent = ''
    for (let i = 0; i < str.length; i++) {
      if (
        (str[i] === '[' && i + 1 <= str.length && str[i + 1] !== ']') ||
        (str[i] === '{' && i + 1 <= str.length && str[i + 1] !== '}')
      ) {
        indent += '  '
        newStr += str[i] + '\n' + indent
      } else if (
        (str[i] === ']' && i - 1 >= 0 && str[i - 1] !== '[') ||
        (str[i] === '}' && i - 1 >= 0 && str[i - 1] !== '{')
      ) {
        indent = indent.substring(0, indent.length - 2)
        newStr += '\n' + indent + str[i]
      } else if (str[i] === ',') {
        newStr += str[i] + '\n' + indent
      } else if (
        !(
          (str[i] === '"' && (str[i - 1] === '{' || str[i - 1] === ',')) ||
          (str[i] === '"' && str[i + 1] === ':')
        )
      ) {
        newStr += str[i]
      }
    }
    return newStr
  }

  /**
   * @description: 处理配置按钮点击
   * @param {*} column
   * @param {*} index
   * @return {*}
   */
  const handleConfigClick = (column, index) => {
    selectedIndex.value = index
    if (column) selectedkey.value = column.formItem.key
    else selectedkey.value = ''
  }

  // 监听是否需要默认值
  watch(
    () => buttonObj.defaultValue,
    (val) => {
      if (val) {
        for (const index in formInit) {
          form.value[index] = { ...formInit[index] }
        }
      } else {
        for (const index in formInit) {
          proxy.$refs[`proFormRef${index}`][0].handleReset()
        }
      }
    }
  )
</script>

<style lang="less" scoped>
  .row {
    width: 100%;
    padding: 20px 0 0 0;
  }
  .label {
    font-weight: 600;
    font-size: 16px;
    margin: 0 10px;
  }
  .button {
    width: 100%;
    display: flex;
    justify-content: flex-start;
    align-content: center;
    > div {
      margin-right: 10px;
      > span {
        padding: 0 10px;
      }
    }
  }
</style>
